import { View } from "@tarojs/components";
import React, { useEffect, useMemo, useRef, useState } from "react";
import moment from "moment";
import { MoneyFormat } from "@/utils/format";
import { HideLoading, ShowLoading, ShowToast, VibrateShort } from "@/utils";
import http from '@/request'
import { billType, dayType } from "@/types";
import './index.scss'


interface moneySummary {
    date: string,
    expense: number,
    income: number,
    balance: number
}

let timer

const CalendarItem: React.FC<{
    displayMonth: string,
    activeDate: string,
    isShow: boolean,
    isExpand: boolean,
    accountId?: number,
    onSelect: (day: dayType) => void,
    onActive: (data: any) => void,
    onExpandChange: () => void
}> = (props) => {
    // 日历日期
    const [days, setDays] = useState<dayType[]>([])
    // 日账单列表
    const [dayBills, setDayBills] = useState<billType[]>([])
    // 日历信息
    const [calendarDays, setCalendarDay] = useState<dayType[]>([])
    const [daySummary, setDaySummary] = useState<moneySummary[]>([])
    const [activeDay, setActiveDay] = useState<dayType | null>(null)
    const weekDays = [{ day: 0, name: '日' },
    { day: 1, name: '一' },
    { day: 2, name: '二' },
    { day: 3, name: '三' },
    { day: 4, name: '四' },
    { day: 5, name: '五' },
    { day: 6, name: '六' }
    ]

    const refObj = useRef<{ monthInfo: any }>({
        monthInfo: null
    })

    const getCalendar = () => {
        http.get("/work-calendar/list", {
            start: moment(props.displayMonth).startOf('month').format('YYYY-MM-DD'),
            end: moment(props.displayMonth).endOf('month').format('YYYY-MM-DD')
        }).then(res => {
            setCalendarDay((res.data || []).map(item => {
                const {date, ...other} = item
                return {
                    ...other,
                    id: item.date
                }
            }))
        })
    }

    const getMonthDays = (displayMonth: string) => {
        const firstDay = moment(displayMonth)
        const start = moment(firstDay).startOf('month')
        const startDate = start.date()
        const startDay = start.day()
        const endDate = moment(firstDay).endOf('month').date()
        const daysArray: dayType[] = []
        for (let i = startDate; i <= endDate; i++) {
            const dayObj = moment(start).add(i - 1, 'days')
            daysArray.push({
                currentMon: true,
                date: dayObj.date(),
                day: dayObj.day(),
                id: dayObj.format('YYYY-MM-DD'),
                data: null
            })
        }
        for (let i = 0; i < startDay; i++) {
            const dayObj = moment(start).subtract(i + 1, 'days')
            daysArray.unshift({
                currentMon: false,
                date: dayObj.date(),
                day: dayObj.day(),
                id: dayObj.format('YYYY-MM-DD'),
                data: null
            })
        }
        // 初始化日期
        setDays(daysArray)
        // 获取日历节气农历
        getCalendar()
        // 获取日期账单数据
        queryList(daysArray)
    }

    const queryList = (daysArray: dayType[]) => {
        if (!props.accountId) return
        const params = {
            page: 1,
            size: 9999,
            accountId: props.accountId,
            startDate: moment(props.displayMonth).startOf('month').format('YYYY-MM-DD'),
            endDate: moment(props.displayMonth).endOf('month').format('YYYY-MM-DD')
        }
        ShowLoading()
        http.post('/bills/page', params).then(res => {
            setDayBills(res.data?.records || [])
            setDaySummary(res.data?.summary || [])

            const summary: moneySummary[] = res.data?.summary || []
            refObj.current.monthInfo = {
                total: res.data?.total || 0,
                income: summary.reduce((sum, cur) => {
                    return cur.income + sum
                }, 0),
                expense: summary.reduce((sum, cur) => {
                    return cur.expense + sum
                }, 0),
                month: moment(props.displayMonth).format('YYYY-MM') + '-01',
                viewHeight: Math.ceil(daysArray.length / 7) * 80 + 114
            }
            if (props.isShow) {
                props.onActive(refObj.current.monthInfo)
            }
            HideLoading()
        }).catch(err => {
            props.onActive({
                expense: 0,
                income: 0,
                month: moment().format("YYYY-MM") + '-01',
                total: 0,
                viewHeight: Math.ceil(daysArray.length / 7) * 80 + 114
            })
            ShowToast(err.msg || '获取账单数据失败')
        })
    }

    const selectDay = (day: dayType) => {   
        setActiveDay(day)
        props.onSelect(day)
    }
    const viewSwitch = () => {
        VibrateShort()
        props.onExpandChange()
    }

    const visibleDays = useMemo(() => {
        let showDates:dayType[] = []
        if (props.isExpand) {
            showDates = [...days]
        } else {
            const activeWeek = Math.floor(days.findIndex(item => {
                return item.id === props.activeDate
            }) / 7)
            showDates = days.filter((_, index) => {
                const curWeek = Math.floor(index / 7)
                return activeWeek <= 0 ? [0, 1].includes(curWeek) : ([0, -1].includes(curWeek - activeWeek))
            })
        }

        const daySummaryMap = daySummary.reduce((sum, cur) => {
            sum[cur.date] = {
                expense: cur.expense,
                income: cur.income,
                balance: cur.balance,
                bills: dayBills.filter(item => {
                    return item.date === cur.date
                })
            }
            return sum
        }, {})

        const calendarDaysMap = calendarDays.reduce((sum, cur) => {
            sum[cur.id || ''] = {
                ...cur
            }
            return sum
        }, {})

        showDates = showDates.map(item => {
            return {
                ...item,
                data: daySummaryMap[item.id || ''] || { expense: 0, income: 0, balance: 0, bills: [] },
                ...(calendarDaysMap[item.id || ''] || {})
            }
        })
        return showDates
    }, [props.isExpand, days, dayBills, daySummary, calendarDays])

    useEffect(() => {
        if (props.isShow) {
            timer && clearTimeout(timer)
            timer = setTimeout(() => {
                const activeDay = visibleDays.find(item => {
                    return item.id === props.activeDate
                })
                if (activeDay) {
                    selectDay(activeDay)
                }
            }, 500)
        }
    }, [visibleDays, props.isShow])

    useEffect(() => {
        getMonthDays(props.displayMonth)
    }, [])

    useEffect(() => {
        if (props.isShow && refObj.current.monthInfo) {
            props.onActive(refObj.current.monthInfo)
        }
    }, [props.isShow])

    // const monthNameShort = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']

    return <View className="calendar-item-container">
        <View className="calendar-month">
            <View className="bg-text text-bg-color">
                {moment(props.displayMonth).format('YYYY-MM')}
            </View>
        </View>
        <View className="date-container flex-row flex-warp">
            {weekDays.map(item => {
                return <View className="day-item calendar-item text-main-color" key={item.day}>{item.name}</View>
            })}
        </View>
        <View className="date-container flex-row flex-warp">
            {visibleDays.map((item) => {
                const className = 'date-item flex-center flex-column calendar-item' +
                    (activeDay?.id === item.id ? ' active' : '') +
                    (item?.id === moment().format('YYYY-MM-DD') ? ' today' : '') +
                    (item.currentMon ? '' : ' view-hide') +
                    ([1, 3].includes(item.status || 4) ? ' holiday' : '')
                return <View className={className} key={item.id} onClick={() => selectDay(item)}>
                    <View className="date-content flex-center flex-column">
                        <View className="date-name text-main-color">{item.date}</View>
                        {item.data?.expense ? <View className="date-money font-size16 money-pay">-{MoneyFormat(item.data.expense)}</View> : null}
                        {item.data?.income ? <View className="date-money font-size16 money-income">+{MoneyFormat(item.data.income)}</View> : null}
                    </View>
                </View>
            })}
        </View>
        <View className="bottom-container flex-column flex-center">
            <View onClick={viewSwitch}>
                <View className="switch-btn border-main-color"></View>
            </View>
        </View>
    </View>
}

export default CalendarItem